home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2008 February / PCWFEB08.iso / Software / Freeware / Miro 1.0 / Miro_Installer.exe / xulrunner / python / test / databasetest.py < prev    next >
Encoding:
Python Source  |  2007-11-12  |  55.9 KB  |  1,462 lines

  1. import unittest
  2. import database
  3. from os import remove
  4. from os.path import expanduser
  5. import random
  6. import config
  7. import prefs
  8. import os
  9. import random
  10. import shutil
  11. import time
  12. import tempfile
  13. import storedatabase
  14. from threading import Thread
  15.  
  16. from test.framework import DemocracyTestCase
  17.  
  18. class SortableObject(database.DDBObject):
  19.     def __init__(self, value):
  20.         self.value = value
  21.         database.DDBObject.__init__(self)
  22.  
  23. class EmptyViewTestCase(DemocracyTestCase):
  24.     def setUp(self):
  25.         DemocracyTestCase.setUp(self)
  26.         self.everything = database.defaultDatabase
  27.     def testCur(self):
  28.         self.everything.resetCursor()
  29.         self.assertEqual(self.everything.cur(),None)
  30.     def testNext(self):
  31.         self.everything.resetCursor()
  32.         self.assertEqual(self.everything.getNext(),None)
  33.     def testGetItem(self):
  34.         self.assertEqual(self.everything[0],None)
  35.     def testGetPrev(self):
  36.         self.everything.resetCursor()
  37.         self.assertEqual(self.everything.getPrev(),None)
  38.     def testLen(self):
  39.         self.assertEqual(self.everything.len(),0)
  40.         
  41. class SingleItemViewTestCase(DemocracyTestCase):
  42.     def setUp(self):
  43.         DemocracyTestCase.setUp(self)
  44.         self.everything = database.defaultDatabase
  45.         self.x = database.DDBObject()
  46.     def testAdd(self):
  47.         self.assertEqual(self.x.__class__, database.DDBObject)
  48.     def testGetItem(self):
  49.         a = self.everything[0]
  50.         b = self.everything[1]
  51.         self.assertEqual(a.__class__, database.DDBObject)
  52.         self.assertEqual(b,None)
  53.     def testNext(self):
  54.         self.everything.resetCursor()
  55.         a = self.everything.cur()
  56.         b = self.everything.getNext()
  57.         c = self.everything.cur()
  58.         d = self.everything.getNext()
  59.         assert ((a == None) and (b.__class__ == database.DDBObject) and
  60.                 (c == b) and (d == None))
  61.     def testGetPrev(self):
  62.         self.everything.resetCursor()
  63.         self.assertEqual(self.everything.getPrev(),None)
  64.     def testLen(self):
  65.         self.assertEqual(self.everything.len(),1)
  66.  
  67. class AddBeforeViewTestCase(DemocracyTestCase):
  68.     def setUp(self):
  69.         DemocracyTestCase.setUp(self)
  70.         self.x = database.DDBObject()
  71.         self.y = database.DDBObject()
  72.         database.resetDefaultDatabase()
  73.         self.everything = database.defaultDatabase
  74.         self.everything.addBeforeCursor(self.y)
  75.         self.everything.resetCursor()
  76.         self.everything.addBeforeCursor(self.x)
  77.     def testUnique(self):
  78.         self.assertNotEqual(self.x,self.y)
  79.     def testUniqueID(self):
  80.         self.assertNotEqual(self.x.getID(),self.y.getID())
  81.     def testGetItem(self):
  82.         a = self.everything[0]
  83.         b = self.everything[1]
  84.         c = self.everything[2]
  85.         self.assertEqual(a.__class__,database.DDBObject)
  86.         self.assertEqual(b.__class__,database.DDBObject)
  87.         self.assertNotEqual(a,b)
  88.         self.assertEqual(c,None)
  89.     def testNextGetPrev(self):
  90.         self.everything.resetCursor()
  91.         a = self.everything.cur()
  92.         b = self.everything.getNext()
  93.         c = self.everything.cur()
  94.         d = self.everything.getNext()
  95.         e = self.everything.cur()
  96.         f = self.everything.getNext()
  97.         assert ((a == None) and (b.__class__ == database.DDBObject) and
  98.                 (c == b) and (d.__class__ == database.DDBObject) and
  99.                 (d != c) and (d == e) and (f == None))
  100.     def testLen(self):
  101.         self.assertEqual(self.everything.len(),2)
  102.  
  103. class AddAfterViewTestCase(DemocracyTestCase):
  104.     def setUp(self):
  105.         DemocracyTestCase.setUp(self)
  106.         self.x = database.DDBObject()
  107.         self.y = database.DDBObject()
  108.         database.resetDefaultDatabase()
  109.         self.everything = database.defaultDatabase
  110.         self.everything.addAfterCursor(self.x)
  111.         self.everything.resetCursor()
  112.         self.everything.getNext()
  113.         self.everything.addAfterCursor(self.y)
  114.     def testUnique(self):
  115.         self.assertNotEqual(self.x,self.y)
  116.     def testUniqueID(self):
  117.         self.assertNotEqual(self.x.getID(),self.y.getID())
  118.     def testGetItem(self):
  119.         a = self.everything[0]
  120.         b = self.everything[1]
  121.         c = self.everything[2]
  122.         self.assertEqual(a.__class__,database.DDBObject)
  123.         self.assertEqual(b.__class__,database.DDBObject)
  124.         self.assertNotEqual(a,b)
  125.         self.assertEqual(c,None)
  126.     def testNextGetPrev(self):
  127.         self.everything.resetCursor()
  128.         a = self.everything.cur()
  129.         b = self.everything.getNext()
  130.         c = self.everything.cur()
  131.         d = self.everything.getNext()
  132.         e = self.everything.cur()
  133.         f = self.everything.getNext()
  134.         assert ((a == None) and (b.__class__ == database.DDBObject) and
  135.                 (c == b) and (d.__class__ == database.DDBObject) and
  136.                 (d != c) and (d == e) and (f == None))
  137.     def testLen(self):
  138.         self.assertEqual(self.everything.len(),2)
  139.  
  140. class DeletedItemViewTestCase(DemocracyTestCase):
  141.     def setUp(self):
  142.         DemocracyTestCase.setUp(self)
  143.         self.everything = database.defaultDatabase
  144.         self.x = database.DDBObject()
  145.         self.y = database.DDBObject()
  146.         self.x.remove()
  147.     def testRemoveMissing(self):
  148.         self.everything.resetCursor()
  149.         self.assertRaises(database.ObjectNotFoundError,self.everything.remove)
  150.     def testAdd(self):
  151.         self.assertEqual(self.x.__class__,database.DDBObject)
  152.     def testGetItem(self):
  153.         a = self.everything[0]
  154.         b = self.everything[1]
  155.         self.assertEqual(a,self.y)
  156.         self.assertEqual(b,None)
  157.     def testNext(self):
  158.         self.everything.resetCursor()
  159.         a = self.everything.cur()
  160.         b = self.everything.getNext()
  161.         c = self.everything.cur()
  162.         d = self.everything.getNext()
  163.         assert ((a == None) and (b.__class__ == database.DDBObject) and
  164.                 (c == b) and (d == None))
  165.     def testLen(self):
  166.         self.assertEqual(self.everything.len(),1)
  167.  
  168. class FilterViewTestCase(DemocracyTestCase):
  169.     def setUp(self):
  170.         DemocracyTestCase.setUp(self)
  171.         self.everything = database.defaultDatabase
  172.         self.x = database.DDBObject()
  173.         self.y = database.DDBObject()
  174.         self.filtered = self.everything.filter(lambda q:q != self.x)
  175.     def testGetItem(self):
  176.         a = self.filtered[0]
  177.         b = self.filtered[1]
  178.         self.assertEqual(a,self.y)
  179.         self.assertEqual(b,None)
  180.     def testNext(self):
  181.         self.filtered.resetCursor()
  182.         a = self.filtered.cur()
  183.         b = self.filtered.getNext()
  184.         c = self.filtered.cur()
  185.         d = self.filtered.getNext()
  186.         assert ((a == None) and (b == self.y) and
  187.                 (c == b) and (d == None))
  188.     def testGetPrev(self):
  189.         self.filtered.resetCursor()
  190.         self.assertEqual(self.filtered.getPrev(),None)
  191.     def testLen(self):
  192.         self.assertEqual(self.filtered.len(),1)
  193.  
  194. class RecomputeFilterViewTestCase(DemocracyTestCase):
  195.     def setUp(self):
  196.         DemocracyTestCase.setUp(self)
  197.         self.everything = database.defaultDatabase
  198.         self.x = database.DDBObject()
  199.         self.y = database.DDBObject()
  200.         self.accept = self.x.getID()
  201.         self.filtered = self.everything.filter(self.changeFilt)
  202.         self.accept = self.y.getID()
  203.         self.everything.recomputeFilters()
  204.     def changeFilt(self, obj):
  205.         return obj.getID() == self.accept
  206.     def testGetItem(self):
  207.         a = self.filtered[0]
  208.         b = self.filtered[1]
  209.         self.assertEqual(a,self.y)
  210.         self.assertEqual(b,None)
  211.     def testNext(self):
  212.         self.filtered.resetCursor()
  213.         a = self.filtered.cur()
  214.         b = self.filtered.getNext()
  215.         c = self.filtered.cur()
  216.         d = self.filtered.getNext()
  217.         assert ((a == None) and (b == self.y) and
  218.                 (c == b) and (d == None))
  219.     def testGetPrev(self):
  220.         self.filtered.resetCursor()
  221.         self.assertEqual(self.filtered.getPrev(),None)
  222.     def testLen(self):
  223.         self.assertEqual(self.filtered.len(),1)
  224.  
  225. class SortTestCase(DemocracyTestCase):
  226.     def setUp(self):
  227.         DemocracyTestCase.setUp(self)
  228.         self.everything = database.defaultDatabase
  229.         self.x = database.DDBObject()
  230.         self.y = database.DDBObject()
  231.         self.higher = self.x
  232.         self.sorted = self.everything.sort(self.sortFunc)
  233.     def sortFunc(self,x,y):
  234.         return x[1] != self.higher
  235.     def testUnique(self):
  236.         self.assertNotEqual(self.x,self.y)
  237.     def testUniqueID(self):
  238.         self.assertNotEqual(self.x.getID(),self.y.getID())
  239.     def testGetItem(self):
  240.         a = self.sorted[0]
  241.         b = self.sorted[1]
  242.         c = self.sorted[2]
  243.         self.assertEqual(a,self.y)
  244.         self.assertEqual(b,self.x)
  245.         self.assertNotEqual(a,b)
  246.         self.assertEqual(c,None)
  247.     def testNextGetPrev(self):
  248.         self.sorted.resetCursor()
  249.         a = self.sorted.cur()
  250.         b = self.sorted.getNext()
  251.         c = self.sorted.cur()
  252.         d = self.sorted.getNext()
  253.         e = self.sorted.cur()
  254.         f = self.sorted.getNext()
  255.         assert ((a == None) and (b.__class__ == database.DDBObject) and
  256.                 (c == b) and (d.__class__ == database.DDBObject) and
  257.                 (d != c) and (d == e) and (f == None))
  258.     def testLen(self):
  259.         self.assertEqual(self.everything.len(),2)
  260.     def testRecompute(self):
  261.         self.higher = self.y
  262.         self.everything.recomputeFilters()
  263.         a = self.sorted[0]
  264.         b = self.sorted[1]
  265.         c = self.sorted[2]
  266.         self.assertEqual(a,self.x)
  267.         self.assertEqual(b,self.y)
  268.         self.assertNotEqual(a,b)
  269.         self.assertEqual(c,None)
  270.     def testSignalChange(self):
  271.         self.higher = self.y
  272.         self.assertEqual(self.sorted[0],self.y)
  273.         self.assertEqual(self.sorted[1],self.x)
  274.         self.x.signalChange()
  275.         self.assertEqual(self.sorted[0],self.y)
  276.         self.assertEqual(self.sorted[1],self.x)
  277.     def testResort(self):
  278.         self.sorted = self.everything.sort(self.sortFunc, resort=True)
  279.         self.assertEqual(self.sorted[0],self.y)
  280.         self.assertEqual(self.sorted[1],self.x)
  281.         self.higher = self.y
  282.         self.x.signalChange()
  283.         self.assertEqual(self.sorted[0],self.x)
  284.         self.assertEqual(self.sorted[1],self.y)
  285.  
  286. class MapViewTestCase(DemocracyTestCase):
  287.     def setUp(self):
  288.         DemocracyTestCase.setUp(self)
  289.         self.everything = database.defaultDatabase
  290.         self.x = database.DDBObject()
  291.         self.y = database.DDBObject()
  292.         self.add = 0
  293.         self.mapped = self.everything.map(self.mapFunc)
  294.     def mapFunc(self,obj):
  295.         return obj.getID()+self.add
  296.     def testNotAltered(self):
  297.         self.assertNotEqual(self.x,self.mapped[0])
  298.         self.assertNotEqual(self.x,self.mapped[1])
  299.         self.assertNotEqual(self.y,self.mapped[0])
  300.         self.assertNotEqual(self.y,self.mapped[1])
  301.     def testUnique(self):
  302.         self.assertNotEqual(self.x,self.y)
  303.     def testUniqueID(self):
  304.         self.assertNotEqual(self.x.getID(),self.y.getID())
  305.     def testGetItem(self):
  306.         a = self.mapped[0]
  307.         b = self.mapped[1]
  308.         c = self.mapped[2]
  309.         self.assertEqual(a,self.everything[0].getID())
  310.         self.assertEqual(b,self.everything[1].getID())
  311.         self.assertNotEqual(a,b)
  312.         self.assertEqual(c,None)
  313.     def testNextGetPrev(self):
  314.         self.mapped.resetCursor()
  315.         a = self.mapped.cur()
  316.         b = self.mapped.getNext()
  317.         c = self.mapped.cur()
  318.         d = self.mapped.getNext()
  319.         e = self.mapped.cur()
  320.         f = self.mapped.getNext()
  321.         assert ((a == None) and (b.__class__.__name__ == 'int') and
  322.                 (c == b) and (d.__class__.__name__ == 'int') and
  323.                 (d != c) and (d == e) and (f == None))
  324.     def testLen(self):
  325.         self.assertEqual(self.everything.len(),2)
  326.  
  327. class CallbackViewTestCase(DemocracyTestCase):
  328.     def setUp(self):
  329.         DemocracyTestCase.setUp(self)
  330.         self.everything = database.defaultDatabase
  331.         self.filtered = self.everything.filter(lambda x:True)
  332.         self.mapped = self.everything.map(lambda x:x)
  333.         self.sorted = self.everything.sort(lambda x,y:0)
  334.         self.callcount = 0
  335.     def call(self, obj, id):
  336.         assert id == self.everything[0].getID()
  337.         self.callcount+=1
  338.     def removeCall(self, obj, id):
  339.         self.callcount+=1
  340.     def testAdd(self):
  341.         self.everything.addAddCallback(self.call)
  342.         self.x = database.DDBObject()
  343.         self.assertEqual(self.callcount,1)
  344.     def testChange(self):
  345.         self.everything.addChangeCallback(self.call)
  346.         self.x = database.DDBObject()
  347.         self.x.signalChange()
  348.         self.assertEqual(self.callcount,1)
  349.     def testRemove(self):
  350.         self.everything.addRemoveCallback(self.removeCall)
  351.         self.x = database.DDBObject()
  352.         self.x.remove()
  353.         self.assertEqual(self.callcount,1)
  354.     def TestFilterAdd(self):
  355.         self.filtered.addAddCallBack(self.call)
  356.         self.x = database.DDBObject()
  357.         self.assertEqual(self.callcount,1)
  358.     def TestFilterRemove(self):
  359.         self.filtered.addRemoveCallBack(self.call)
  360.         self.x = database.DDBObject()
  361.         self.x.remove()
  362.         self.assertEqual(self.callcount,1)
  363.     def TestFilterChange(self):
  364.         self.filtered.addChangeCallBack(self.call)
  365.         self.x = database.DDBObject()
  366.         self.x.change()
  367.         self.assertEqual(self.callcount,1)
  368.     def TestMapAdd(self):
  369.         self.mapped.addAddCallBack(self.call)
  370.         self.x = database.DDBObject()
  371.         self.assertEqual(self.callcount,1)
  372.     def TestMapRemove(self):
  373.         self.mapped.addRemoveCallBack(self.call)
  374.         self.x = database.DDBObject()
  375.         self.x.remove()
  376.         self.assertEqual(self.callcount,1)
  377.     def TestMapChange(self):
  378.         self.mapped.addChangeCallBack(self.call)
  379.         self.x = database.DDBObject()
  380.         self.x.change()
  381.         self.assertEqual(self.callcount,1)
  382.     def TestSortAdd(self):
  383.         self.sorted.addAddCallBack(self.call)
  384.         self.x = database.DDBObject()
  385.         self.assertEqual(self.callcount,1)
  386.     def TestSortRemove(self):
  387.         self.sorted.addRemoveCallBack(self.call)
  388.         self.x = database.DDBObject()
  389.         self.x.remove()
  390.         self.assertEqual(self.callcount,1)
  391.     def TestSortChange(self):
  392.         self.sorted.addChangeCallBack(self.call)
  393.         self.x = database.DDBObject()
  394.         self.x.change()
  395.         self.assertEqual(self.callcount,1)
  396.  
  397. class SaveRestoreTestCase(DemocracyTestCase):
  398.     def setUp(self):
  399.         DemocracyTestCase.setUp(self)
  400.         self.tempdb = os.path.join(tempfile.gettempdir(), 'democracy-temp-db')
  401.         self.everything = database.defaultDatabase
  402.         self.everything.liveStorage = storedatabase.LiveStorage(self.tempdb,
  403.                 restore=False)
  404.         self.x = database.DDBObject()
  405.         self.y = database.DDBObject()
  406.     def tearDown(self):
  407.         self.everything.liveStorage.close()
  408.         self.everything.liveStorage = None
  409.         try:
  410.             shutil.rmtree(self.tempdb)
  411.         except:
  412.             pass
  413.         DemocracyTestCase.tearDown(self)
  414.  
  415. class BasicSaveTestCase(SaveRestoreTestCase):
  416.     def testSaveRestore(self):
  417.         self.assertEqual(self.everything.len(),2)
  418.         self.everything.liveStorage.saveDatabase()
  419.         self.everything.liveStorage.close()
  420.         self.z = database.DDBObject()
  421.         self.zz = database.DDBObject()
  422.         self.assertEqual(self.everything.len(),4)
  423.         last = self.zz.getID()
  424.         self.x.remove()
  425.         self.everything.liveStorage = storedatabase.LiveStorage(self.tempdb)
  426.         self.assertEqual(self.everything.len(),2)
  427.         assert (self.everything[0].getID() == self.y.getID() or
  428.                 self.everything[0].getID() == self.x.getID())
  429.         if self.everything[0].getID() == self.y.getID():
  430.             self.assertEqual(self.everything[1].getID(),self.x.getID())
  431.         if self.everything[0].getID() == self.x.getID():
  432.             self.assertEqual(self.everything[1].getID(),self.y.getID())
  433.         self.assertEqual(self.everything[2],None)
  434.         assert database.DDBObject().getID() >= last
  435.     def testLastID(self):
  436.         last = self.y.getID()
  437.         self.everything.liveStorage.saveDatabase()
  438.         # Simulate restarting app
  439.         self.y.remove()
  440.         self.x.remove()
  441.         database.DDBObject.lastID = 0 # This is implementation specific and
  442.                              # needs to be updated when the
  443.                              # implementation changes
  444.         self.everything.liveStorage = storedatabase.LiveStorage(self.tempdb)
  445.         assert database.DDBObject().getID() > last
  446.  
  447. class MapFilterRemoveViewTestCase(DemocracyTestCase):
  448.     def setUp(self):
  449.         DemocracyTestCase.setUp(self)
  450.         self.everything = database.defaultDatabase
  451.         self.objlist = []
  452.         for x in range(0,10):
  453.             database.DDBObject()
  454.         self.add = 0
  455.         self.mapped = self.everything.map(self.mapFunc)
  456.         self.mapped = self.mapped.filter(lambda x:True)
  457.     def mapFunc(self,obj):
  458.         return obj.getID() % 2
  459.     def testBasicMap(self):
  460.         self.everything.resetCursor()
  461.         self.mapped.resetCursor()
  462.         for obj in self.everything:
  463.             self.assertEqual(self.mapFunc(obj),self.mapped.getNext())
  464.     def testOneOffBasicMap(self):
  465.         self.everything.resetCursor()
  466.         self.mapped.resetCursor()
  467.         for x in range(1,6):
  468.             obj = self.everything.getNext()
  469.         obj.remove()
  470.         self.everything.addBeforeCursor(database.DDBObject(add=False))
  471.         self.everything.getPrev()
  472.         self.everything.getPrev()
  473.         self.everything.addAfterCursor(database.DDBObject(add=False))
  474.         self.everything.resetCursor()
  475.         for obj in self.everything:
  476.             self.assertEqual(self.mapFunc(obj),self.mapped.getObjectByID(obj.getID()))
  477.  
  478. class FilterSortMapTestCase(DemocracyTestCase):
  479.     def setUp(self):
  480.         DemocracyTestCase.setUp(self)
  481.         self.everything = database.defaultDatabase
  482.         self.callbacks = 0
  483.         self.objlist = []
  484.         for x in range(0,10):
  485.             self.objlist.append(database.DDBObject())
  486.         self.myfiltFunc = lambda x:x.getID()%2 == 0
  487.         self.filted = self.everything.filter(self.filterFunc)
  488.         self.sorted = self.filted.sort(self.sortFunc)
  489.         self.mapped = self.sorted.map(lambda x:x)
  490.     def filterFunc(self, x):
  491.         return self.myfiltFunc(x)
  492.     def sortFunc(self, x, y):
  493.         x = x[1].getID()
  494.         y = y[1].getID()
  495.         return x < y
  496.     def call(self,obj, id):
  497.         self.callbacks += 1
  498.     def test(self):
  499.         self.assertEqual(self.mapped.len(),5)
  500.         self.mapped.addAddCallback(self.call)
  501.         self.myfiltFunc = lambda x:x is self.objlist[1]
  502.         self.everything.recomputeFilters()
  503.         self.assertEqual(self.mapped.len(),1)
  504.         self.myfiltFunc = lambda x:True
  505.         self.everything.recomputeFilters()
  506.         self.assertEqual(self.mapped.len(),10)
  507.     def testTwoSets(self):
  508.         self.callbacks2 = 0
  509.         def call2(item,id):
  510.             self.callbacks2 += 1
  511.         filtFunc2 = lambda x:True
  512.         filted2 = self.everything.filter(filtFunc2)
  513.         sorted2 = filted2.sort(self.sortFunc)
  514.         mapped2 = sorted2.map(lambda x:x)
  515.         self.mapped.addChangeCallback(self.call)
  516.         mapped2.addChangeCallback(call2)
  517.         if self.myfiltFunc(self.objlist[0]):
  518.             self.objlist[1].signalChange()
  519.         else:
  520.             self.objlist[0].signalChange()
  521.         self.assertEqual(self.callbacks,0)
  522.         self.assertEqual(self.callbacks2,1)
  523.         self.everything.recomputeFilters()
  524.         self.assertEqual(self.callbacks,0)
  525.         self.assertEqual(self.callbacks2,1)
  526.         self.everything.recomputeFilters()
  527.         self.assertEqual(self.callbacks,0)
  528.         self.assertEqual(self.callbacks2,1)
  529.         if self.myfiltFunc(self.objlist[0]):
  530.             self.objlist[0].signalChange()
  531.         else:
  532.             self.objlist[1].signalChange()
  533.         self.assertEqual(self.callbacks,1)
  534.         self.assertEqual(self.callbacks2,2)
  535.         self.everything.recomputeFilters()
  536.         self.assertEqual(self.callbacks,1)
  537.         self.assertEqual(self.callbacks2,2)
  538.         self.everything.recomputeFilters()
  539.         self.assertEqual(self.callbacks,1)
  540.         self.assertEqual(self.callbacks2,2)
  541.     def testTwoSets2(self):
  542.         self.callbacks2 = 0
  543.         def call2(item, id):
  544.             self.callbacks2 += 1
  545.         filtFunc2 = lambda x:x.getID()%2 == 1
  546.         filted2 = self.everything.filter(filtFunc2)
  547.         sorted2 = filted2.sort(self.sortFunc)
  548.         mapped2 = sorted2.map(lambda x:x)
  549.         self.mapped.addChangeCallback(self.call)
  550.         mapped2.addChangeCallback(call2)
  551.         self.mapped.addAddCallback(self.call)
  552.         mapped2.addAddCallback(call2)
  553.         self.mapped.addRemoveCallback(self.call)
  554.         mapped2.addRemoveCallback(call2)
  555.  
  556.         self.mapped.next()
  557.         self.mapped.next()
  558.         self.mapped.next()
  559.         mapped2.next()
  560.         self.assertEqual(self.mapped.cur(),self.mapped[2])
  561.         self.assertEqual(mapped2.cur(),mapped2[0])
  562.         if self.myfiltFunc(self.objlist[0]):
  563.             self.objlist[1].signalChange()
  564.         else:
  565.             self.objlist[0].signalChange()
  566.         self.assertEqual(self.mapped.cur(),self.mapped[2])
  567.         self.assertEqual(mapped2.cur(),mapped2[0])
  568.         self.assertEqual(self.callbacks,0)
  569.         self.assertEqual(self.callbacks2,1)
  570.         self.everything.recomputeFilters()
  571.         self.assertEqual(self.mapped.cur(),self.mapped[2])
  572.         self.assertEqual(mapped2.cur(),mapped2[0])
  573.         self.assertEqual(self.callbacks,0)
  574.         self.assertEqual(self.callbacks2,1)
  575.         self.everything.recomputeFilters()
  576.         self.assertEqual(self.mapped.cur(),self.mapped[2])
  577.         self.assertEqual(mapped2.cur(),mapped2[0])
  578.         self.assertEqual(self.callbacks,0)
  579.         self.assertEqual(self.callbacks2,1)
  580.         if self.myfiltFunc(self.objlist[0]):
  581.             self.objlist[0].signalChange()
  582.         else:
  583.             self.objlist[1].signalChange()
  584.         self.assertEqual(self.mapped.cur(),self.mapped[2])
  585.         self.assertEqual(mapped2.cur(),mapped2[0])
  586.         self.assertEqual(self.callbacks,1)
  587.         self.assertEqual(self.callbacks2,1)
  588.         self.everything.recomputeFilters()
  589.         self.assertEqual(self.mapped.cur(),self.mapped[2])
  590.         self.assertEqual(mapped2.cur(),mapped2[0])
  591.         self.assertEqual(self.callbacks,1)
  592.         self.assertEqual(self.callbacks2,1)
  593.         self.everything.recomputeFilters()
  594.         self.assertEqual(self.mapped.cur(),self.mapped[2])
  595.         self.assertEqual(mapped2.cur(),mapped2[0])
  596.         self.assertEqual(self.callbacks,1)
  597.         self.assertEqual(self.callbacks2,1)
  598.         if self.myfiltFunc(self.objlist[0]):
  599.             self.objlist[0].remove()
  600.         else:
  601.             self.objlist[1].remove()
  602.         self.assertEqual(self.mapped.cur(),self.mapped[1])
  603.         self.assertEqual(mapped2.cur(),mapped2[0])
  604.         self.assertEqual(self.callbacks,2)
  605.         self.assertEqual(self.callbacks2,1)
  606.         self.everything.recomputeFilters()
  607.         self.assertEqual(self.mapped.cur(),self.mapped[1])
  608.         self.assertEqual(mapped2.cur(),mapped2[0])
  609.         self.assertEqual(self.callbacks,2)
  610.         self.assertEqual(self.callbacks2,1)
  611.         self.everything.recomputeFilters()
  612.         self.assertEqual(self.mapped.cur(),self.mapped[1])
  613.         self.assertEqual(mapped2.cur(),mapped2[0])
  614.         self.assertEqual(self.callbacks,2)
  615.         self.assertEqual(self.callbacks2,1)
  616.         self.objlist.append(database.DDBObject(add = False))
  617.         self.objlist.append(database.DDBObject(add = False))
  618.         self.everything.resetCursor()
  619.         self.everything.addAfterCursor(self.objlist[10])
  620.         self.assertEqual(self.everything[0],self.objlist[10])
  621.         self.assertEqual(self.everything.cur(),None)
  622.         self.everything.addAfterCursor(self.objlist[11])
  623.         self.assertEqual(self.everything[0],self.objlist[11])
  624.         self.assertEqual(self.mapped.cur(),self.mapped[1])
  625.         self.assertEqual(mapped2.cur(),mapped2[0])
  626.         self.assertEqual(self.callbacks,3)
  627.         self.assertEqual(self.callbacks2,2)
  628.         self.objlist[10].signalChange()
  629.         self.objlist[11].signalChange()
  630.         self.assertEqual(self.mapped.cur(),self.mapped[1])
  631.         self.assertEqual(mapped2.cur(),mapped2[0])
  632.         self.assertEqual(self.callbacks,4)
  633.         self.assertEqual(self.callbacks2,3)
  634.         self.everything.recomputeFilters()
  635.         self.assertEqual(self.callbacks,4)
  636.         self.assertEqual(self.callbacks2,3)
  637.         self.myfiltFunc = lambda x:x is self.objlist[2]
  638.         self.everything.recomputeFilters()
  639.         self.assertEqual(self.callbacks2,3)
  640.         self.objlist[2].signalChange()
  641.         self.objlist[3].signalChange()
  642.         self.assertEqual(self.callbacks2,4)
  643.         
  644. class CursorTestCase(DemocracyTestCase):
  645.     def setUp(self):
  646.         DemocracyTestCase.setUp(self)
  647.         self.everything = database.defaultDatabase
  648.         self.origObjs = [database.DDBObject(), database.DDBObject(), database.DDBObject()]
  649.         self.objs = self.everything.filter(lambda x: True).map(self.mapToObject).sort(self.sortOldID)
  650.     def sortOldID(self,x,y):
  651.         return x[1].oldID < y[1].oldID
  652.     def mapToObject(self, obj):
  653.         temp = database.DDBObject(add = False)
  654.         temp.oldID = obj.getID()
  655.         return temp
  656.     def test(self):
  657.         self.assertEqual(self.objs.len(),3)
  658.         self.assertEqual(self.objs.cur(),None)
  659.         self.objs.getNext()
  660.         self.objs.getNext()
  661.         self.objs.getNext()
  662.         self.assertEqual(self.objs.cur(),self.objs[2])
  663.         self.origObjs[2].remove()
  664.         self.assertEqual(self.objs.cur(),self.objs[1])
  665.         self.objs.getPrev()
  666.         self.assertEqual(self.objs.cur(),self.objs[0])
  667.     def testStack(self):
  668.         obj = self.everything.getNext()
  669.         self.assertEqual(self.everything.cur(), obj)
  670.         self.everything.saveCursor()
  671.         while self.everything.getNext() is not None:
  672.             pass
  673.         self.everything.restoreCursor()
  674.         self.assertEqual(self.everything.cur(), obj)
  675.  
  676. class RecomputeMapTestCase(DemocracyTestCase):
  677.     def setUp(self):
  678.         DemocracyTestCase.setUp(self)
  679.         self.everything = database.defaultDatabase
  680.         self.origObjs = [database.DDBObject(), database.DDBObject(), database.DDBObject()]
  681.         self.objs = self.everything.filter(lambda x: True).map(self.mapToObject).sort(self.sortOldID).map(self.mapToObject)
  682.         self.changeCalls = 0
  683.     def sortOldID(self,x,y):
  684.         return x[1].oldID < y[1].oldID
  685.     def mapToObject(self, obj):
  686.         temp = database.DDBObject(add = False)
  687.         temp.oldID = obj.getID()
  688.         return temp
  689.     def changeCall(self,item,id):
  690.         self.changeCalls +=1
  691.     def test(self):
  692.         self.objs.addChangeCallback(self.changeCall)
  693.         self.everything.recomputeFilters()
  694.         self.everything.recomputeFilters()
  695.         temp = self.everything.getNext()
  696.         temp.signalChange()
  697.         self.assertEqual(self.changeCalls,1)
  698.  
  699. class FilterUpdateOnChange(DemocracyTestCase):
  700.     def setUp(self):
  701.         DemocracyTestCase.setUp(self)
  702.         self.everything = database.defaultDatabase
  703.         self.origObjs = [database.DDBObject(), database.DDBObject(), database.DDBObject()]
  704.         self.origObjs[0].good = True
  705.         self.origObjs[1].good = False
  706.         self.origObjs[2].good = False
  707.         self.objs = self.everything.filter(lambda x: x.good)
  708.         self.changeCalls = 0
  709.     def testLoss(self):
  710.         self.assertEqual(self.objs.len(),1)
  711.         self.origObjs[0].good = False
  712.         self.origObjs[0].signalChange()
  713.         self.assertEqual(self.objs.len(),0)
  714.     def testAdd(self):
  715.         self.assertEqual(self.objs.len(),1)
  716.         self.origObjs[1].good = True
  717.         self.origObjs[1].signalChange()
  718.         self.assertEqual(self.objs.len(),2)
  719.  
  720. # Currently, we require that the database does NOT update maps on a change
  721. class MapUpdateOnChange(DemocracyTestCase):
  722.     def setUp(self):
  723.         DemocracyTestCase.setUp(self)
  724.         self.everything = database.defaultDatabase
  725.         self.origObjs = [database.DDBObject(), database.DDBObject(), database.DDBObject()]
  726.         self.origObjs[0].good = True
  727.         self.origObjs[1].good = False
  728.         self.origObjs[2].good = False
  729.         self.objs = self.everything.map(self.mapToObject).filter(lambda x: x.good)
  730.         self.changeCalls = 0
  731.     def mapToObject(self, obj):
  732.         temp = database.DDBObject(add = False)
  733.         temp.good = obj.good
  734.         return temp
  735.     def testLoss(self):
  736.         self.assertEqual(self.objs.len(),1)
  737.         self.origObjs[0].good = False
  738.         self.origObjs[0].signalChange()
  739.         self.assertEqual(self.objs.len(),1)
  740.     def testAdd(self):
  741.         self.assertEqual(self.objs.len(),1)
  742.         self.origObjs[1].good = True
  743.         self.origObjs[1].signalChange()
  744.         self.assertEqual(self.objs.len(),1)
  745.  
  746. class SortUpdateOnChange(DemocracyTestCase):
  747.     def setUp(self):
  748.         DemocracyTestCase.setUp(self)
  749.         self.everything = database.defaultDatabase
  750.         self.origObjs = [database.DDBObject(), database.DDBObject(), database.DDBObject()]
  751.         self.origObjs[0].good = True
  752.         self.origObjs[1].good = False
  753.         self.origObjs[2].good = False
  754.         self.objs = self.everything.sort(lambda x, y: 0).sort(lambda x, y: 0).filter(lambda x: x.good)
  755.         self.changeCalls = 0
  756.     def testLoss(self):
  757.         self.assertEqual(self.objs.len(),1)
  758.         self.origObjs[0].good = False
  759.         self.origObjs[0].signalChange()
  760.         self.assertEqual(self.objs.len(),0)
  761.     def testAdd(self):
  762.         self.assertEqual(self.objs.len(),1)
  763.         self.origObjs[1].good = True
  764.         self.origObjs[1].signalChange()
  765.         self.assertEqual(self.objs.len(),2)
  766.  
  767. class IDBaseTraversal(DemocracyTestCase):
  768.     def setUp(self):
  769.         DemocracyTestCase.setUp(self)
  770.         self.everything = database.defaultDatabase
  771.         self.origObjs = [database.DDBObject(), database.DDBObject(), database.DDBObject()]
  772.         self.sorted = self.everything.sort(self.sortID)
  773.     def sortID(self,x,y):
  774.         return x[1].getID() < y[1].getID()
  775.     def test(self):
  776.         self.assertEqual(self.origObjs[0],
  777.                          self.sorted.getObjectByID(self.origObjs[0].getID()))
  778.         self.assertEqual(self.origObjs[1],
  779.                          self.sorted.getObjectByID(self.origObjs[1].getID()))
  780.         self.assertEqual(self.origObjs[2],
  781.                          self.sorted.getObjectByID(self.origObjs[2].getID()))
  782.         
  783.         self.assertEqual(self.origObjs[1].getID(),
  784.                          self.sorted.getNextID(self.origObjs[0].getID()))
  785.         self.assertEqual(self.origObjs[2].getID(),
  786.                          self.sorted.getNextID(self.origObjs[1].getID()))
  787.         self.assertEqual(None,self.sorted.getNextID(self.origObjs[2].getID()))
  788.  
  789.         self.assertEqual(None,self.sorted.getPrevID(self.origObjs[0].getID()))
  790.         self.assertEqual(self.origObjs[0].getID(),
  791.                          self.sorted.getPrevID(self.origObjs[1].getID()))
  792.         self.assertEqual(self.origObjs[1].getID(),
  793.                          self.sorted.getPrevID(self.origObjs[2].getID()))
  794.     
  795.         self.sorted.resetCursor()
  796.         self.sorted.getNext()
  797.         self.assertEqual(self.origObjs[0].getID(), self.sorted.getCurrentID())
  798.         self.sorted.getNext()
  799.         self.assertEqual(self.origObjs[1].getID(), self.sorted.getCurrentID())
  800.         self.sorted.getNext()
  801.         self.assertEqual(self.origObjs[2].getID(), self.sorted.getCurrentID())
  802.  
  803. # class ThreadTest(DemocracyTestCase):
  804. #     def setUp(self):
  805. #         self.everything = database.defaultDatabase
  806. #     def add100(self):
  807. #         for x in range(0,100):
  808. #             database.DDBObject()
  809. #     def remove100(self):
  810. #         for x in range(0,100):
  811. #             self.everything[0].remove()
  812. #     def testAddRemove(self):
  813. #         self.add100()
  814. #         thread = Thread(target = self.add100)
  815. #         thread.setDaemon(False)
  816. #         thread.start()
  817. #         self.remove100()
  818. #         thread.join()
  819.  
  820. class IndexFilterTestBase(DemocracyTestCase):
  821.     def setUp(self):
  822.         DemocracyTestCase.setUp(self)
  823.         self.everything = database.defaultDatabase
  824.         self.addCallbacks = 0
  825.         self.removeCallbacks = 0
  826.         self.changeCallbacks = 0
  827.     def addCallback(self,value,id):
  828.         self.addCallbacks += 1
  829.     def removeCallback(self,value,id):
  830.         self.removeCallbacks += 1
  831.     def changeCallback(self,value,id):
  832.         self.changeCallbacks += 1
  833.  
  834. class IndexFilterTest(IndexFilterTestBase):
  835.     def setUp(self):
  836.         IndexFilterTestBase.setUp(self)
  837.         self.shift = 0
  838.     def mod10(self, x):
  839.         return (x.getID() + self.shift) % 10
  840.     def mod100(self, x):
  841.         return (x.getID() + self.shift) % 100
  842.     def sortIndexFunc(self, x, y):
  843.         return x[1].myValue < y[1].myValue
  844.     def sortFunc(self, x, y):
  845.         x = x[1].getID()
  846.         y = y[1].getID()
  847.         return x < y
  848.     def testBasicIndexFilter(self):
  849.         for x in range(0,100):
  850.             database.DDBObject()
  851.         self.everything.createIndex(self.mod10)
  852.         filtered = self.everything.filterWithIndex(self.mod10,0)
  853.         self.assertEqual(filtered.len(),10)
  854.         for x in range(0,50):
  855.             database.DDBObject()
  856.         self.assertEqual(filtered.len(),15)
  857.         for i in range(10):
  858.             obj = self.everything.getItemWithIndex(self.mod10, i)
  859.             self.assertEqual(self.mod10(obj), i)
  860.         obj = self.everything.getItemWithIndex(self.mod10, 10)
  861.         self.assertEqual(obj, None)
  862.         obj = self.everything.getItemWithIndex(self.mod10, -1, default=123123)
  863.         self.assertEqual(obj, 123123)
  864.         filtered.addAddCallback(self.addCallback)
  865.         filtered.addRemoveCallback(self.removeCallback)
  866.         filtered.addChangeCallback(self.changeCallback)
  867.         for x in range(0,50):
  868.             database.DDBObject()
  869.  
  870.         self.assertEqual(self.addCallbacks,5)
  871.         for obj in filtered:
  872.             self.assertEqual(self.mod10(obj),0)
  873.         filtered[0].remove()
  874.         self.assertEqual(filtered.len(),19)
  875.         self.assertEqual(self.removeCallbacks,1)
  876.         filtered[0].signalChange()
  877.         self.assertEqual(self.changeCallbacks,1)
  878.  
  879.         obj = filtered[0]
  880.         self.everything.removeView(filtered)
  881.         for x in range(0,50):
  882.             database.DDBObject()
  883.         self.assertEqual(self.addCallbacks,5)
  884.         obj.signalChange()
  885.         self.assertEqual(self.changeCallbacks,1)
  886.         obj.remove()
  887.         self.assertEqual(self.removeCallbacks,1)
  888.     def testIndexChanges(self):
  889.         class IndexedObject(database.DDBObject):
  890.             def __init__(self, myValue):
  891.                 database.DDBObject.__init__(self)
  892.                 self.myValue = myValue
  893.         def indexFunc(obj):
  894.             return obj.myValue
  895.         foo = IndexedObject('blue')
  896.         bar = IndexedObject('red')
  897.         baz = IndexedObject('red')
  898.         self.everything.createIndex(indexFunc)
  899.         blueView = self.everything.filterWithIndex(indexFunc, 'blue')
  900.         redView = self.everything.filterWithIndex(indexFunc, 'red')
  901.         self.assertEquals(blueView.len(), 1)
  902.         self.assertEquals(redView.len(), 2)
  903.         baz.myValue = 'blue'
  904.         baz.signalChange()
  905.         self.assertEquals(blueView.len(), 2)
  906.         self.assertEquals(redView.len(), 1)
  907.         # test changing to a new view that we've never referenced before.
  908.         foo.myValue = 'green'
  909.         foo.signalChange()
  910.         greenView = self.everything.filterWithIndex(indexFunc, 'green')
  911.         self.assertEquals(blueView.len(), 1)
  912.         self.assertEquals(redView.len(), 1)
  913.         self.assertEquals(greenView.len(), 1)
  914.     def testRemoveIndexedView(self):
  915.         for x in range(0,100):
  916.             database.DDBObject()
  917.         self.everything.createIndex(self.mod10)
  918.         views = [self.everything.filterWithIndex(self.mod10, i) \
  919.                 for i in range(10)]
  920.         # remove half the views with parent.removeView()
  921.         for view in views[:5]:
  922.             self.everything.removeView(view)
  923.         # remove the other half with unlink()
  924.         for view in views[5:]:
  925.             view.unlink()
  926.     def testRecomputeIndex(self):
  927.         for x in range(0,100):
  928.             database.DDBObject()
  929.         self.everything.createIndex(self.mod10)
  930.         for x in range(0,50):
  931.             database.DDBObject()
  932.         filtered = self.everything.filterWithIndex(self.mod10,0)
  933.         for x in range(0,50):
  934.             database.DDBObject()
  935.         self.assertEqual(filtered.len(),20)
  936.         filtered[0].remove()
  937.         self.assertEqual(filtered.len(),19)
  938.         self.shift = 1
  939.         self.everything.recomputeFilters()
  940.         self.assertEqual(filtered.len(),20)
  941.     def testLargeSet(self):
  942.         self.everything.createIndex(self.mod100)
  943.         start = time.clock()
  944.         for x in range(0,500):
  945.             database.DDBObject()
  946.             database.DDBObject()
  947.             database.DDBObject()
  948.             database.DDBObject()
  949.             database.DDBObject()
  950.             database.DDBObject()
  951.             database.DDBObject()
  952.             database.DDBObject()
  953.             database.DDBObject()
  954.             database.DDBObject()
  955.         mid = time.clock()
  956.         for x in range(0,500):
  957.             database.DDBObject()
  958.             database.DDBObject()
  959.             database.DDBObject()
  960.             database.DDBObject()
  961.             database.DDBObject()
  962.             database.DDBObject()
  963.             database.DDBObject()
  964.             database.DDBObject()
  965.             database.DDBObject()
  966.             database.DDBObject()
  967.         end = time.clock()
  968.         # Make sure insert time doesn't increase as the size of the
  969.         # database increases
  970.         assert ( (end-mid) - (mid-start) < (mid-start)/2)
  971.         filtered = self.everything.filterWithIndex(self.mod100,0).sort(self.sortFunc)
  972.         self.assertEqual(filtered.len(),100)
  973.     def testSortedIndex(self):
  974.         class IndexedObject(database.DDBObject):
  975.             def __init__(self, myValue):
  976.                 self.myValue = myValue
  977.                 database.DDBObject.__init__(self)
  978.         self.everything.createIndex(self.mod10,self.sortIndexFunc, resort = True)
  979.         self.objects = []
  980.         for x in range(100):
  981.             self.objects.append(IndexedObject(x))
  982.  
  983.         # Test basic sorting
  984.         filtered = self.everything.filterWithIndex(self.mod10,0)
  985.         self.assertEqual(filtered.len(), 10)
  986.         last = None
  987.         for obj in filtered:
  988.             if last is not None:
  989.                 self.assert_(last.myValue < obj.myValue)
  990.             last = obj
  991.  
  992.         # Test changing values without signaling
  993.         filtered[0].myValue = 1000
  994.         filtered[1].myValue = -1000
  995.  
  996.         unordered = False
  997.         last = None
  998.         filtered.resetCursor()
  999.         for obj in filtered:
  1000.             if last is not None:
  1001.                 if not (last.myValue < obj.myValue):
  1002.                     unordered = True
  1003.             last = obj
  1004.         self.assert_(unordered)
  1005.  
  1006.         # Test that things get re-ordered correctly on signalChange
  1007.         filtered[0].signalChange()
  1008.         filtered[1].signalChange()
  1009.         last = None
  1010.         filtered.resetCursor()
  1011.         for obj in filtered:
  1012.             if last is not None:
  1013.                 self.assert_(last.myValue < obj.myValue)
  1014.             last = obj
  1015.         # Test that a new filter on the index is sorted
  1016.         filtered2 = self.everything.filterWithIndex(self.mod10,0)
  1017.         self.assertEqual(filtered2.len(), 10)
  1018.         last = None
  1019.         for obj in filtered2:
  1020.             if last is not None:
  1021.                 self.assert_(last.myValue < obj.myValue)
  1022.             last = obj
  1023.  
  1024.     def testChangeIndexValue(self):
  1025.         for x in range(0,100):
  1026.             database.DDBObject()
  1027.         self.everything.createIndex(self.mod10, sortFunc=self.sortFunc, resort = True)
  1028.         filtered = self.everything.filterWithIndex(self.mod10,0)
  1029.         filtered.addAddCallback(self.addCallback)
  1030.         filtered.addRemoveCallback(self.removeCallback)
  1031.         filtered.addChangeCallback(self.changeCallback)
  1032.  
  1033.         filtered.changeIndexValue(self.mod10, 1)
  1034.         self.assertEqual(filtered.len(),10)
  1035.         self.assertEqual(self.addCallbacks,10)
  1036.         self.assertEqual(self.removeCallbacks,10)
  1037.         self.assertEqual(self.changeCallbacks,0)
  1038.  
  1039.         filtered.resetCursor()
  1040.         filtered3 = self.everything.filterWithIndex(self.mod10,0)
  1041.         filtered2 = self.everything.filterWithIndex(self.mod10,1)
  1042.         for obj in filtered2:
  1043.             self.assertEqual(filtered.getNext().id, obj.id)
  1044.             self.assertNotEqual(filtered3.getNext().id, obj.id)
  1045.  
  1046.         for x in range(0,100):
  1047.             database.DDBObject()
  1048.         self.assertEqual(filtered.len(),20)
  1049.         self.assertEqual(self.addCallbacks,20)
  1050.  
  1051.         filtered.changeIndexValue(self.mod10, 0)
  1052.         filtered.resetCursor()
  1053.         filtered2.resetCursor()
  1054.         filtered3.resetCursor()
  1055.         for obj in filtered3:
  1056.             self.assertEqual(filtered.getNext().id, obj.id)
  1057.             self.assertNotEqual(filtered2.getNext().id, obj.id)
  1058.         self.assertEqual(filtered.len(),20)
  1059.         self.assertEqual(self.addCallbacks,40)
  1060.         self.assertEqual(self.removeCallbacks,30)
  1061.         self.assertEqual(self.changeCallbacks,0)
  1062.         self.everything.removeView(filtered)
  1063.         for x in range(0,100):
  1064.             database.DDBObject()
  1065.         self.assertEqual(self.addCallbacks,40)
  1066.         self.assertEqual(self.removeCallbacks,30)
  1067.         self.assertEqual(self.changeCallbacks,0)
  1068.         
  1069. class MultiIndexed(database.DDBObject):
  1070.     def __init__(self, indexValues):
  1071.         self.indexValues = indexValues
  1072.         database.DDBObject.__init__(self)
  1073. def testMultiIndex(obj):
  1074.     return obj.indexValues
  1075.  
  1076. class MultiIndexTestCase(IndexFilterTestBase):
  1077.     def setUp(self):
  1078.         IndexFilterTestBase.setUp(self)
  1079.         random.seed(12341234)
  1080.         self.allObjects = []
  1081.         self.objectsByValueCount = {}
  1082.         for i in range(20):
  1083.             self.newObject()
  1084.         self.everything.createIndex(testMultiIndex, multiValued=True)
  1085.  
  1086.     def genRandomValues(self):
  1087.         values = set()
  1088.         for i in xrange(random.randint(0, 4)):
  1089.             values.add(random.randint(0, 10))
  1090.         return list(values)
  1091.  
  1092.     def newObject(self):
  1093.         indexValues = self.genRandomValues()
  1094.         obj = MultiIndexed(indexValues)
  1095.         self.allObjects.append(obj)
  1096.         try:
  1097.             self.objectsByValueCount[len(indexValues)].append(obj)
  1098.         except KeyError:
  1099.             self.objectsByValueCount[len(indexValues)] = [obj]
  1100.  
  1101.     def checkViews(self):
  1102.         viewsShouldHave = {}
  1103.         for obj in self.allObjects:
  1104.             for value in obj.indexValues:
  1105.                 try:
  1106.                     viewsShouldHave[value].add(obj)
  1107.                 except KeyError:
  1108.                     viewsShouldHave[value] = set([obj])
  1109.         for value, goal in viewsShouldHave.items():
  1110.             filtered = self.everything.filterWithIndex(testMultiIndex, value)
  1111.             reality = set([obj for obj in filtered])
  1112.             self.assertEqual(goal, reality)
  1113.  
  1114.     def testInitalViews(self):
  1115.         self.checkViews()
  1116.  
  1117.     def testRemove(self):
  1118.         while self.allObjects:
  1119.             obj = self.allObjects.pop()
  1120.             obj.remove()
  1121.             self.checkViews()
  1122.  
  1123.     def testChange(self):
  1124.         for obj in self.allObjects:
  1125.             obj.indexValues = self.genRandomValues()
  1126.             obj.signalChange(needsSave=False)
  1127.             self.checkViews()
  1128.  
  1129.     def testCallbacks(self):
  1130.         filtered = self.everything.filterWithIndex(testMultiIndex, 0)
  1131.         filtered.addAddCallback(self.addCallback)
  1132.         filtered.addRemoveCallback(self.removeCallback)
  1133.         filtered.addChangeCallback(self.changeCallback)
  1134.         addCallbackGoal = removeCallbackGoal = changeCallbackGoal = 0
  1135.         for obj in self.allObjects:
  1136.             newValues = self.genRandomValues()
  1137.             if 0 in newValues:
  1138.                 if 0 not in obj.indexValues:
  1139.                     addCallbackGoal += 1
  1140.                 else:
  1141.                     changeCallbackGoal += 1
  1142.             elif 0 in obj.indexValues:
  1143.                 removeCallbackGoal += 1
  1144.             obj.indexValues = newValues
  1145.             obj.signalChange(needsSave=False)
  1146.             self.assertEquals(self.changeCallbacks, changeCallbackGoal)
  1147.             self.assertEquals(self.addCallbacks, addCallbackGoal)
  1148.             self.assertEquals(self.removeCallbacks, removeCallbackGoal)
  1149.  
  1150. class ReSortTestCase(DemocracyTestCase):
  1151.     def setUp(self):
  1152.         DemocracyTestCase.setUp(self)
  1153.         self.everything = database.defaultDatabase
  1154.         self.addCallbacks = 0
  1155.         self.removeCallbacks = 0
  1156.         self.changeCallbacks = 0
  1157.         self.objlist = []
  1158.         for x in range(0,10):
  1159.             self.objlist.append(SortableObject(x))
  1160.         self.sorted = self.everything.sort(self.sortFunc, resort = True)
  1161.         self.sorted.addAddCallback(self.addCall)
  1162.         self.sorted.addRemoveCallback(self.removeCall)
  1163.         self.sorted.addChangeCallback(self.changeCall)
  1164.  
  1165.     def sortFunc(self, x, y):
  1166.         return x[1].value < y[1].value
  1167.  
  1168.     def addCall(self, obj, id):
  1169.         # We have a convention of setting the cursor after the object
  1170.         self.assertEqual(self.sorted.getPrev().getID(),id)
  1171.         
  1172.         self.addCallbacks += 1
  1173.  
  1174.     def removeCall(self, obj, id):
  1175.         self.removeCallbacks += 1
  1176.  
  1177.     def changeCall(self, obj, id):
  1178.         self.changeCallbacks += 1
  1179.  
  1180.     def testResort(self):
  1181.         self.sorted.resetCursor()
  1182.         last = None
  1183.         for obj in self.sorted:
  1184.             if last is not None:
  1185.                 self.assert_(last.value < obj.value)
  1186.             last = obj
  1187.             
  1188.         self.objlist[0].value = 100
  1189.         self.objlist[0].signalChange()
  1190.  
  1191.         self.sorted.resetCursor()
  1192.         last = None
  1193.         for obj in self.sorted:
  1194.             if last is not None:
  1195.                 self.assert_(last.value < obj.value)
  1196.             last = obj
  1197.         self.assertEqual(self.addCallbacks, 1)
  1198.         self.assertEqual(self.removeCallbacks, 1)
  1199.         self.assertEqual(self.changeCallbacks, 0)
  1200.  
  1201. class SortingFilterTestCase(DemocracyTestCase):
  1202.     def setUp(self):
  1203.         DemocracyTestCase.setUp(self)
  1204.         self.everything = database.defaultDatabase
  1205.         self.sortCalls = 0
  1206.         self.objs = []
  1207.         self.reversed = False
  1208.  
  1209.     def sortFunc(self, x, y):
  1210.         self.sortCalls += 1
  1211.         return x[1].value < y[1].value
  1212.  
  1213.     def sortFuncReversable(self, x, y):
  1214.         self.sortCalls += 1
  1215.         retval = x[1].value < y[1].value
  1216.         if self.reversed:
  1217.             retval = not retval
  1218.         return retval
  1219.  
  1220.     def testSort(self):
  1221.         sortView = self.everything.sort(self.sortFunc)
  1222.         for x in range(2000):
  1223.             a = SortableObject(2000)
  1224.             self.objs.append(a)
  1225.         initialSorts = self.sortCalls
  1226.         self.sortCalls = 0
  1227.         filtView = sortView.filter(lambda x:True,sortFunc=self.sortFunc)
  1228.         filterSorts = self.sortCalls
  1229.         self.sortCalls = 0
  1230.  
  1231.         self.assertEqual(sortView.len(),filtView.len())
  1232.         sortView.resetCursor()
  1233.         filtView.resetCursor()
  1234.         for obj in sortView:
  1235.             self.assertEqual(obj,filtView.getNext())
  1236.  
  1237.         self.objs[-1].value = -10
  1238.         self.objs[-1].signalChange()
  1239.         self.objs[-2].value = 0
  1240.         self.objs[-2].signalChange()
  1241.         self.assertEqual(self.sortCalls, 0)
  1242.         sortView.unlink()
  1243.         filtView.unlink()
  1244.  
  1245.     def testResort(self):
  1246.         sortView = self.everything.sort(self.sortFunc, resort = True)
  1247.         for x in range(2000):
  1248.             a = SortableObject(x)
  1249.             self.objs.append(a)
  1250.         initialSorts = self.sortCalls
  1251.         self.sortCalls = 0
  1252.         filtView = sortView.filter(lambda x:True,sortFunc=self.sortFunc,
  1253.                                    resort=True)
  1254.         filterSorts = self.sortCalls
  1255.         self.sortCalls = 0
  1256.  
  1257.         self.assertEqual(sortView.len(),filtView.len())
  1258.         sortView.resetCursor()
  1259.         filtView.resetCursor()
  1260.         last = None
  1261.         for obj in sortView:
  1262.             self.assertEqual(obj,filtView.getNext())
  1263.             if last != None:
  1264.                 self.assert_(obj.value >= last.value)
  1265.             last = obj
  1266.  
  1267.         self.objs[-1].value = -10
  1268.         self.objs[-1].signalChange()
  1269.         self.objs[-2].value = -1
  1270.         self.objs[-2].signalChange()
  1271.         self.assert_(self.sortCalls > 0)
  1272.  
  1273.         sortView.resetCursor()
  1274.         filtView.resetCursor()
  1275.         last = None
  1276.         for obj in sortView:
  1277.             self.assertEqual(obj,filtView.getNext())
  1278.             if last != None:
  1279.                 self.assert_(obj.value >= last.value)
  1280.             last = obj
  1281.         
  1282.         sortView.unlink()
  1283.         filtView.unlink()
  1284.  
  1285.     def testPerformance(self):
  1286.         # Filtering an already sorted list with a sort must be O(n)
  1287.         #
  1288.         # In other words, we need to make sure that the list isn't
  1289.         # being resorted
  1290.         sortView = self.everything.sort(self.sortFunc)
  1291.         initialSorts = []
  1292.         filterSorts = []
  1293.         for n in [100, 900, 9100]:
  1294.             for x in range(n):
  1295.                 a = SortableObject(n)
  1296.                 self.objs.append(a)
  1297.             initialSorts.append(self.sortCalls)
  1298.             self.sortCalls = 0
  1299.             filtView = sortView.filter(lambda x:True,sortFunc=self.sortFunc)
  1300.             filterSorts.append(self.sortCalls)
  1301.             self.sortCalls = 0
  1302.         ratio1 = float(filterSorts[1])/filterSorts[0]
  1303.         ratio2 = float(filterSorts[2])/filterSorts[1]
  1304.  
  1305.         # Make sure the ratios are within 1% of each other
  1306.         self.assert_(abs(ratio1-ratio2)/ratio1 < 0.01)
  1307.  
  1308.     def testResortFilter(self):
  1309.         filtView = self.everything.filter(lambda *args: True, resort=True, sortFunc=self.sortFuncReversable)
  1310.         self.reversed = False
  1311.         for i in range (20):
  1312.             a = SortableObject(i)
  1313.             self.objs.append(a)
  1314.         for i in range (20):
  1315.             self.assertEqual(filtView[i].value, i)
  1316.         self.reversed = True
  1317.         for i in range (20):
  1318.             self.assertEqual(filtView[i].value, i)
  1319.         self.everything.recomputeSort(filtView)
  1320.         for i in range (20):
  1321.             self.assertEqual(filtView[i].value, 19 - i)
  1322.  
  1323.     def testExplicitResort(self):
  1324.         def indexFunc(x):
  1325.             return True
  1326.         def indexFunc2(x):
  1327.             return True
  1328.         def multiIndexFunc(x):
  1329.             return [True]
  1330.         def multiIndexFunc2(x):
  1331.             return [True]
  1332.         
  1333.         sortView = self.everything.sort(self.sortFunc, resort = True)
  1334.         for x in range(2000):
  1335.             a = SortableObject(x)
  1336.             self.objs.append(a)
  1337.         initialSorts = self.sortCalls
  1338.         self.sortCalls = 0
  1339.  
  1340.         subSort = sortView.sort(self.sortFunc, resort = True)
  1341.         unSubSort = sortView.sort(self.sortFunc, resort = False)
  1342.         sortingFiltView = sortView.filter(lambda x:True,sortFunc=self.sortFunc,
  1343.                                    resort=True)
  1344.         unsortingFiltView = sortView.filter(lambda x:True,sortFunc=self.sortFunc,
  1345.                                             resort=False)
  1346.         
  1347.         sortView.createIndex(indexFunc,sortFunc=self.sortFunc, resort = True)
  1348.         sortingIndexView = sortView.filterWithIndex(indexFunc, True)
  1349.  
  1350.         sortView.createIndex(indexFunc2,sortFunc=self.sortFunc, resort = False)
  1351.         unsortingIndexView = sortView.filterWithIndex(indexFunc2, True)
  1352.  
  1353.         sortView.createIndex(multiIndexFunc,sortFunc=self.sortFunc, resort = True,
  1354.                              multiValued = True)
  1355.         sortingMultiIndexView = sortView.filterWithIndex(multiIndexFunc, True)
  1356.         
  1357.         sortView.createIndex(multiIndexFunc2,sortFunc=self.sortFunc, resort = False,
  1358.                              multiValued = True)
  1359.         unsortingMultiIndexView = sortView.filterWithIndex(multiIndexFunc2, True)
  1360.  
  1361.         allMyViews = [sortingFiltView, unsortingFiltView,
  1362.                       sortingIndexView, unsortingIndexView,
  1363.                       sortingMultiIndexView, unsortingMultiIndexView,
  1364.                       subSort, unSubSort]
  1365.  
  1366.         allSortingViews = [subSort, sortingFiltView, sortingIndexView,
  1367.                            sortingMultiIndexView]
  1368.  
  1369.         allUnSortingViews = [unsortingFiltView, unSubSort,
  1370.                              unsortingIndexView, unsortingMultiIndexView]
  1371.  
  1372.         for view in allMyViews:
  1373.             self.assertEqual(sortView.len(),view.len())
  1374.             view.resetCursor()
  1375.  
  1376.             last = None
  1377.             sortView.resetCursor()
  1378.             for obj in sortView:
  1379.                 self.assertEqual(obj,view.getNext())
  1380.                 if last != None:
  1381.                     self.assert_(obj.value >= last.value)
  1382.                 last = obj
  1383.  
  1384.         self.objs[-1].value = -10
  1385.         self.objs[-2].value = -1
  1386.         self.everything.recomputeSort(sortView)
  1387.         self.assert_(self.sortCalls > 0)
  1388.  
  1389.         for view in allUnSortingViews:
  1390.             self.assertEqual(sortView.len(),view.len())
  1391.             view.resetCursor()
  1392.             sortView.resetCursor()
  1393.             for obj in sortView:
  1394.                 self.assertNotEqual(obj,view.getNext())
  1395.  
  1396.         for view in allSortingViews:
  1397.             self.assertEqual(sortView.len(),view.len())
  1398.             view.resetCursor()
  1399.             last = None
  1400.             sortView.resetCursor()
  1401.             for obj in sortView:
  1402.                 self.assertEqual(obj,view.getNext())
  1403.                 if last != None:
  1404.                     self.assert_(obj.value >= last.value)
  1405.                 last = obj
  1406.  
  1407.         sortView.unlink()
  1408.         for view in allMyViews:
  1409.             view.unlink()
  1410.  
  1411. class UnlinkViewTestCase(DemocracyTestCase):
  1412.     def setUp(self):
  1413.         self.sortCalls = 0
  1414.         DemocracyTestCase.setUp(self)
  1415.         self.everything = database.defaultDatabase
  1416.         self.x = database.DDBObject()
  1417.         self.y = database.DDBObject()
  1418.         self.parent = self.everything.filter(lambda q: True)
  1419.         self.filtered = self.parent.filter(lambda q: True)
  1420.         self.sorted = self.parent.sort(self.sortFunc)
  1421.         self.mapped = self.parent.map(lambda x: x)
  1422.         self.index = self.parent.createIndex(self.indexFunc)
  1423.         self.indexed = self.parent.filterWithIndex(self.indexFunc, True)
  1424.  
  1425.     def indexFunc(self, x):
  1426.         return True
  1427.  
  1428.     def sortFunc(self, x, y):
  1429.         self.sortCalls += 1
  1430.         return str(x[1]) < str(y[1])
  1431.  
  1432.     def testUnlink(self):
  1433.         self.assertEqual(len(self.filtered), len(self.parent))
  1434.         self.assertEqual(len(self.sorted), len(self.parent))
  1435.         self.assertEqual(len(self.mapped), len(self.parent))
  1436.         self.assertEqual(len(self.indexed), len(self.parent))
  1437.         numSort = self.sortCalls
  1438.         
  1439.         self.filtered.unlink()
  1440.         self.sorted.unlink()
  1441.         self.mapped.unlink()
  1442.         self.indexed.unlink()
  1443.         self.x.remove()
  1444.  
  1445.         self.assertNotEqual(len(self.filtered), len(self.parent))
  1446.         self.assertNotEqual(len(self.sorted), len(self.parent))
  1447.         self.assertNotEqual(len(self.mapped), len(self.parent))
  1448.         self.assertNotEqual(len(self.indexed), len(self.parent))
  1449.         self.assertEqual(numSort, self.sortCalls)
  1450.  
  1451.         self.x = database.DDBObject()
  1452.         self.z = database.DDBObject()
  1453.  
  1454.         self.assertNotEqual(len(self.filtered), len(self.parent))
  1455.         self.assertNotEqual(len(self.sorted), len(self.parent))
  1456.         self.assertNotEqual(len(self.mapped), len(self.parent))
  1457.         self.assertNotEqual(len(self.indexed), len(self.parent))
  1458.         self.assertEqual(numSort, self.sortCalls)
  1459.  
  1460. if __name__ == "__main__":
  1461.     unittest.main()
  1462.